package com.zhangjinghao.controller;

import com.alibaba.fastjson.JSON;
import com.zhangjinghao.entity.Contract;
import com.zhangjinghao.entity.SelectArg;
import com.zhangjinghao.es.ContractRepository;
import com.zhangjinghao.service.ContractService;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Controller
@RequestMapping("contract")
public class ContractController {

    @Autowired
    private ContractService contractService;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private ContractRepository contractRepository;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;


    /**
     * 跳转列表
     * @param selectArg
     * @return
     */
    @RequestMapping("list")
    public String list(SelectArg selectArg){

        //进行es初始化设置
        if (!redisTemplate.hasKey("init")){
            init();
        }

        //进行es查询与条件存入
        request.setAttribute("list",selectInES(selectArg));
        request.setAttribute("arg",selectArg);

        return "contract-list";
    }

    /**
     * es初始化
     */
    public void init(){
        List<Contract> list = contractService.list();
        for (Contract contract : list) {
            contractRepository.save(contract);
        }
        redisTemplate.opsForValue().set("init",null,new Random().nextInt(1000)+1000, TimeUnit.MINUTES);
    }

    /**
     * es查询
     * @param selectArg
     * @return
     */
    public List<Contract> selectInES(SelectArg selectArg){

        //构建查询对象
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

        //设置关键字全局查询
        if (StringUtils.hasText(selectArg.getKeyword())){
            MultiMatchQueryBuilder multiMatchQuery = QueryBuilders.multiMatchQuery(selectArg.getKeyword(), "deptNo", "roomName", "houseName", "premiseName", "peopleNum", "tenantName", "tenantPhone", "tenantEmergencyPhone", "tenantCardNo", "tenantContactAddress", "cfUserName");
            boolQueryBuilder.must(multiMatchQuery);
        }

        //设置高光字段
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("deptNo").field("roomName").field("houseName").field("premiseName").field("peopleNum").field("tenantName").field("tenantPhone").field("tenantEmergencyPhone").field("tenantCardNo").field("tenantContactAddress").field("cfUserName");
        //为此字段内容添加左右标签
        highlightBuilder.preTags("<font color='blue'>").postTags("</font>");

        //设置区间查询
        if (selectArg.getMin()!=null||selectArg.getMin()!=null){
            RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("peopleNum");
            if (selectArg.getMin()!=null){
                rangeQuery.gte(selectArg.getMin());
            }
            if (selectArg.getMax()!=null){
                rangeQuery.lte(selectArg.getMax());
            }
            boolQueryBuilder.must(rangeQuery);
        }
        
        //设置定值查询
        if (selectArg.getDeptId()!=null){
            TermQueryBuilder termQuery = QueryBuilders.termQuery("deptId", selectArg.getDeptId());
            boolQueryBuilder.must(termQuery);
        }


        SearchResponse contract_index = elasticsearchTemplate.getClient()
                .prepareSearch("contract_index")
                .highlighter(highlightBuilder)
                .setQuery(boolQueryBuilder)
                .setFrom((selectArg.getPageNum() - 1) * selectArg.getPageSize())
                .setSize(selectArg.getPageSize())
                .get();

        SearchHits hits = contract_index.getHits();

        List<Contract> list = new ArrayList<>();

        for (SearchHit hit:hits
             ) {
            //1、通过JSON.parseObject将source下的内容转换成实体类型
            Contract contract = JSON.parseObject(hit.getSourceAsString(), Contract.class);

            //2、获取高亮字段的map集合
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();

            for (String key:highlightFields.keySet()
                 ) {
                //获得高亮内容
                Text text = highlightFields.get(key).fragments()[0];
                //高亮对应属性
                Field field = null;
                try {
                    field = Contract.class.getDeclaredField(key);
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                }
                if (text!=null && field!=null){
                    //强制剔除访问修饰符
                    field.setAccessible(true);
                    //使用高亮字段替换原有属性内容
                    try {
                        field.set(contract,text.toString());
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
            //  将修改完毕的对象存入集合
            list.add(contract);
        }

        return list;
    }


}
